﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SenseTimeTracker.BusinessLayer;
using SenseTimeTracker.CommonSenseControls;
using SenseTimeTracker.Misc;
using SenseTimeTracker.Properties;
using StedySoft.SenseSDK;
using StedySoft.SenseSDK.DrawingCE;

namespace SenseTimeTracker.TimeCards
{
	public partial class TimeCardEditForm : CommonSenseForm
	{
		private bool sipInitialized = false;
		private TimeCard timeCard;
		private bool considerCompletedTasks;

		private SensePanelComboItem clientComboBoxItem;
		private SensePanelComboItem projectComboBoxItem;
		private SensePanelComboItem taskComboBoxItem;
		private SensePanelDateTimeItemEx taskStartDateTimeItem;
		private SensePanelDateTimeItemEx taskFinalDateTimeItem;
		private SensePanelTextboxItem taskDescriptionItem;
		private SensePanelTextboxItem taskDetailsItem;
		private bool autoDescription = false;

		public TimeCardEditForm()
		{
			InitializeComponent();

			senseHeaderCtrl.Text = Resources.TimeCardEditHeader;

			clientComboBoxItem = new SensePanelComboItem();
			clientComboBoxItem.LabelText = string.Format("{0}:", Resources.ClientLabel);
			clientComboBoxItem.ShowSeparator = true;
			clientComboBoxItem.OnSelectedValueChanged += clientComboBoxItem_OnSelectedValueChanged;

			projectComboBoxItem = new SensePanelComboItem();
			projectComboBoxItem.LabelText = string.Format("{0}:", Resources.ProjectLabel);
			projectComboBoxItem.ShowSeparator = true;
			projectComboBoxItem.OnSelectedValueChanged += projectComboBoxItem_OnSelectedValueChanged;

			taskComboBoxItem = new SensePanelComboItem();
			taskComboBoxItem.LabelText = string.Format("{0}:", Resources.TaskLabel);
			taskComboBoxItem.ShowSeparator = true;
			taskComboBoxItem.OnSelectedValueChanged += taskComboBoxItem_OnSelectedValueChanged;

			taskStartDateTimeItem = new SensePanelDateTimeItemEx();
			taskStartDateTimeItem.LabelText = string.Format("{0}:", Resources.StartTimeLabel);
			taskStartDateTimeItem.ShowSeparator = true;
			taskStartDateTimeItem.OnDateTimeChanged += taskStartDateTimeItem_OnDateTimeChanged;

			taskFinalDateTimeItem = new SensePanelDateTimeItemEx();
			taskFinalDateTimeItem.LabelText = string.Format("{0}:", Resources.FinalTimeLabel);
			taskFinalDateTimeItem.ShowSeparator = true;
			taskFinalDateTimeItem.OnDateTimeChanged += taskFinalDateTimeItem_OnDateTimeChanged;


			taskDescriptionItem = new SensePanelTextboxItem();
			taskDescriptionItem.LabelText = string.Format("{0}:", Resources.DescriptionLabel);
			taskDescriptionItem.Text = string.Empty;
			taskDescriptionItem.MaxLength = DatabaseManager.MaxTimeCardDescriptionLength;
			taskDescriptionItem.ShowSeparator = true;
			taskDescriptionItem.TextChanged += taskDescriptionItem_TextChanged;

			taskDetailsItem = new SensePanelTextboxItem();
			taskDetailsItem.LabelText = string.Format("{0}:", Resources.DetailsLabel);
			taskDetailsItem.Multiline = true;
			taskDetailsItem.Height = 200;
			taskDetailsItem.MaxLength = DatabaseManager.MaxTimeCardDetailsLength;
			taskDetailsItem.Text = string.Empty;
			taskDetailsItem.ShowSeparator = true;
		}

		void taskDescriptionItem_TextChanged(object sender, EventArgs e)
		{
			if (!autoDescription)
			{
				timeCard.NewCard = false;
			}
		}

		public TimeCard TimeRecord
		{
			get { return timeCard; }
			set { timeCard = value; }
		}

		public bool ConsiderCompletedTasks
		{
			get { return considerCompletedTasks; }
			set { considerCompletedTasks = value; }
		}

		void taskStartDateTimeItem_OnDateTimeChanged(object Sender, DateTime DateTime)
		{
			AdjustToQuarterOfAnHour(taskStartDateTimeItem);
			if (taskFinalDateTimeItem.DateTime < taskStartDateTimeItem.DateTime)
			{
				taskFinalDateTimeItem.DateTime = taskStartDateTimeItem.DateTime.Date + taskFinalDateTimeItem.DateTime.TimeOfDay;
			}

			if (taskFinalDateTimeItem.DateTime < taskStartDateTimeItem.DateTime)
			{
				taskFinalDateTimeItem.DateTime = taskStartDateTimeItem.DateTime;
			}
		}

		void taskFinalDateTimeItem_OnDateTimeChanged(object Sender, DateTime DateTime)
		{
			AdjustToQuarterOfAnHour(taskFinalDateTimeItem);
			if (taskFinalDateTimeItem.DateTime < taskStartDateTimeItem.DateTime && taskFinalDateTimeItem.DateTime.TimeOfDay.TotalMinutes > 0)
			{
				taskStartDateTimeItem.DateTime = taskFinalDateTimeItem.DateTime.Date + taskStartDateTimeItem.DateTime.TimeOfDay;
			}

			if (taskFinalDateTimeItem.DateTime < taskStartDateTimeItem.DateTime && taskFinalDateTimeItem.DateTime.TimeOfDay.TotalMinutes > 0)
			{
				taskStartDateTimeItem.DateTime = taskFinalDateTimeItem.DateTime;
			}
		}

		/// <summary>
		/// Adjusts the value of a datetime picker to a quarter of an hour.
		/// The use of up/down arrows is assumed the values to be 1, 16, 31, 46 respective 14, 29, 44 and 59.
		/// In this case the time is adjusted to the next respective prevoius quarter of an hour.
		/// Other values are assumed to be entered manueally, they are adjustet allways to the previous quarter of an hour.
		/// </summary>
		/// <param name="dateTimePicker">The date time picker to adjust</param>
		private void AdjustToQuarterOfAnHour(SensePanelDateTimeItemEx dateTimePicker)
		{
			switch (dateTimePicker.DateTime.Minute % 15)
			{
				case 1:
					dateTimePicker.DateTime += TimeSpan.FromMinutes(14);
					break;
				case 14:
					dateTimePicker.DateTime -= TimeSpan.FromMinutes(14);
					if (dateTimePicker.DateTime.Minute == 45)
					{
						dateTimePicker.DateTime -= TimeSpan.FromHours(1);
					}

					break;
				default:
					dateTimePicker.DateTime -= TimeSpan.FromMinutes(dateTimePicker.DateTime.Minute % 15);
					break;
			}
		}

		void clientComboBoxItem_OnSelectedValueChanged(object Sender, object Value)
		{
			timeCard.Client = (Guid)Value;
			projectComboBoxItem.Items.Clear();
			Binder.BindCombobox(projectComboBoxItem.Items, timeCard.Client, Guid.Empty, false, considerCompletedTasks);
			projectComboBoxItem.SelectedValue = timeCard.Project;
			if (projectComboBoxItem.SelectedIndex == -1)
			{
				projectComboBoxItem.SelectedIndex = 0;
				timeCard.Project = (Guid)projectComboBoxItem.Items[0].Value;
			}
		}

		void projectComboBoxItem_OnSelectedValueChanged(object Sender, object Value)
		{
			timeCard.Project = (Guid)Value;
			taskComboBoxItem.Items.Clear();
			Binder.BindCombobox(taskComboBoxItem.Items, timeCard.Client, timeCard.Project, false, considerCompletedTasks);
			taskComboBoxItem.SelectedValue = timeCard.Task;
			if (taskComboBoxItem.SelectedIndex == -1)
			{
				taskComboBoxItem.SelectedIndex = 0;
				timeCard.Task = (Guid)taskComboBoxItem.Items[0].Value;
			}
		}

		void taskComboBoxItem_OnSelectedValueChanged(object Sender, object Value)
		{
			if (timeCard.NewCard && (Guid)taskComboBoxItem.SelectedValue != DatabaseManager.AllTasksId)
			{
				autoDescription = true;
				taskDescriptionItem.Text = Task.GetTask((Guid)taskComboBoxItem.SelectedValue).DefaultDescription;
				autoDescription = false;
			}
		}

		protected override void OnLoad(EventArgs e)
		{
			Bind();
			if (string.IsNullOrEmpty(taskDescriptionItem.Text))
			{
				autoDescription = true;
				taskDescriptionItem.Text = Task.GetTask((Guid)taskComboBoxItem.SelectedValue).DefaultDescription;
				autoDescription = false;
			}
			base.OnLoad(e);
		}

		private void Bind()
		{
			clientComboBoxItem.Items.Clear();
			Binder.BindCombobox(clientComboBoxItem.Items, Guid.Empty, Guid.Empty, false, considerCompletedTasks);
			if (clientComboBoxItem.Items.Count == 0)
			{
				SenseAPIs.SenseMessageBox.Show(Resources.DialogMessageNoSuitableTasksFound, Resources.DialogHeaderEditTimeCard, SenseMessageBoxButtons.OK);
				DialogResult = DialogResult.Cancel;
				return;
			}

			clientComboBoxItem.SelectedValue = timeCard.Client;
			if (clientComboBoxItem.SelectedIndex == -1)
			{
				clientComboBoxItem.SelectedIndex = 0;
				timeCard.Client = (Guid)clientComboBoxItem.Items[0].Value;
			}

			projectComboBoxItem.Items.Clear();
			Binder.BindCombobox(projectComboBoxItem.Items, timeCard.Client, Guid.Empty, false, considerCompletedTasks);
			projectComboBoxItem.SelectedValue = timeCard.Project;
			if (projectComboBoxItem.SelectedIndex == -1)
			{
				projectComboBoxItem.SelectedIndex = 0;
				timeCard.Project = (Guid)projectComboBoxItem.Items[0].Value;
			}

			taskComboBoxItem.Items.Clear();
			Binder.BindCombobox(taskComboBoxItem.Items, timeCard.Client, timeCard.Project, false, considerCompletedTasks);
			taskComboBoxItem.SelectedValue = timeCard.Task;
			if (taskComboBoxItem.SelectedIndex == -1)
			{
				taskComboBoxItem.SelectedIndex = 0;
				timeCard.Task = (Guid)taskComboBoxItem.Items[0].Value;
			}

			taskStartDateTimeItem.DateTime = timeCard.StartDateTime;
			taskFinalDateTimeItem.DateTime = timeCard.FinalDateTime;
			taskDescriptionItem.Text = timeCard.Description;
			taskDetailsItem.Text = timeCard.Details;

			senseListCtrl.AddItem(new SensePanelDividerItem(string.Empty, Resources.TimeCardsEditExplanation));
			senseListCtrl.AddItem(clientComboBoxItem);
			senseListCtrl.AddItem(projectComboBoxItem);
			senseListCtrl.AddItem(taskComboBoxItem);
			senseListCtrl.AddItem(taskStartDateTimeItem);
			senseListCtrl.AddItem(taskFinalDateTimeItem);
			senseListCtrl.AddItem(taskDescriptionItem);
			senseListCtrl.AddItem(taskDetailsItem);

			if (!sipInitialized)
			{
				sipInitialized = true;
				SIP.Enable(senseListCtrl.Handle);
			}
		}

		protected override void OnClosing(CancelEventArgs e)
		{
			if (DialogResult == DialogResult.OK)
			{
				timeCard.Client = (Guid)clientComboBoxItem.SelectedValue;
				timeCard.Project = (Guid)projectComboBoxItem.SelectedValue;
				timeCard.Task = (Guid)taskComboBoxItem.SelectedValue;
				timeCard.StartDateTime = taskStartDateTimeItem.DateTime;
				timeCard.FinalDateTime = taskFinalDateTimeItem.DateTime;
				timeCard.Description = taskDescriptionItem.Text;
				timeCard.Details = taskDetailsItem.Text;
			}

			base.OnClosing(e);
		}
	}
}